package com.prac.redis.controller;

import cn.hutool.core.util.StrUtil;
import com.google.code.kaptcha.Producer;
import com.prac.common.result.DataResult;
import com.prac.common.result.Result;
import com.prac.redis.util.CommonUtil;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 图片验证码工具接口
 *
 * @author hxg
 * @version 1.0
 * @date 2022/5/2 16:57
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/captcha")
public class CaptchaController {

    private final RedisTemplate<String, Object> redisTemplate;
    private final Producer captchaProducer;

    /**
     * 图形验证码
     *
     * @param request
     * @param response
     */
    @GetMapping("pic")
    public Result getCaptcha(HttpServletRequest request, HttpServletResponse response) {
        String key = getKey(request);
        String captchaCode = captchaProducer.createText();
        redisTemplate.opsForValue().set(key, captchaCode, 10, TimeUnit.MINUTES);
        BufferedImage image = captchaProducer.createImage(captchaCode);
        ServletOutputStream outputStream;
        try {
            outputStream = response.getOutputStream();
            ImageIO.write(image, "jpg", outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new Result();
    }

    private String getKey(HttpServletRequest request) {
        String ipAddr = CommonUtil.getIpAddr(request);
        String header = request.getHeader("User-Agent");
        return "user:captcha:" + CommonUtil.MD5(ipAddr + header);
    }

    /**
     * 手机验证码
     * @param phone
     * @return
     */
    @GetMapping("phone")
    public DataResult<String> phoneCaptcha(@RequestParam String phone) {
        String sendCode = sendVCode(phone);
        log.info("手机验证码结果|<|>|{}|<|>|{}", phone, registryCode(phone, sendCode));
        return new DataResult<>(sendCode);
    }

    private String registryCode(String phone, String verifyCode) {
        String isExist = (String) redisTemplate.opsForValue().get(phone + ":code");
        if (isExist == null || !isExist.equals(verifyCode)) {
            return "验证码不正确";
        } else {
            return "登录成功";
        }
    }

    //每个手机每5min只能发送1次，验证码放redis中，设置过期时间
    private String sendVCode(String phone) {
        String countKey = phone + ":count";
        String codeKey = phone + ":code";

        int count = Integer.parseInt(StrUtil.blankToDefault((String) redisTemplate.opsForValue().get(countKey),"0"));
        if(count != 0){
            return "5min后再试";
        }
        redisTemplate.opsForValue().set(countKey, "1",5, TimeUnit.MINUTES);
        String code = getCode();
        redisTemplate.opsForValue().set(codeKey, code,5, TimeUnit.MINUTES);
        return code;
    }

    private String getCode() {
        Random random = new Random();
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 5; i++) {
            int m = random.nextInt(10);
            builder.append(m);
        }
        return builder.toString();
    }

}
